#include "Logger.h"
#include <QDateTime>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QDir>

// 静态成员初始化
Logger *Logger::s_instance = nullptr;
QMutex Logger::s_mutex;

Logger::Logger(QObject *parent)
    : QObject(parent),
      m_initialized(false),
      m_fileLoggingEnabled(false),
      m_logLevel(Info),
      m_logFile(nullptr),
      m_logStream(nullptr)
{
}

Logger::~Logger()
{
    close();
}

// 获取单例实例
Logger *Logger::instance()
{
    if (s_instance == nullptr)
    {
        QMutexLocker locker(&s_mutex);
        if (s_instance == nullptr)
        {
            s_instance = new Logger();
        }
    }
    return s_instance;
}

// 初始化日志系统
bool Logger::initialize(const QString &logFilePath)
{
    if (m_initialized)
    {
        qWarning() << "日志系统已初始化";
        return true;
    }

    // 检查数据库是否已初始化
    DatabaseService *dbService = DatabaseService::instance();
    if (!dbService->isInitialized())
    {
        qCritical() << "日志系统初始化失败：数据库未初始化";
        return false;
    }

    // 如果指定了日志文件路径，则启用文件日志
    if (!logFilePath.isEmpty())
    {
        m_logFilePath = logFilePath;

        // 确保日志目录存在
        QFileInfo fileInfo(m_logFilePath);
        QDir dir = fileInfo.absoluteDir();
        if (!dir.exists())
        {
            dir.mkpath(".");
        }

        m_logFile = new QFile(m_logFilePath);
        if (m_logFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
        {
            m_logStream = new QTextStream(m_logFile);
            m_logStream->setCodec("UTF-8");
            m_fileLoggingEnabled = true;
            qInfo() << "✅ 文件日志已启用:" << m_logFilePath;
        }
        else
        {
            qWarning() << "⚠️ 无法打开日志文件:" << m_logFilePath;
            delete m_logFile;
            m_logFile = nullptr;
        }
    }

    m_initialized = true;
    qInfo() << "✅ 日志系统初始化完成";

    // 记录系统启动日志
    logOperation("system_start", "Logger", "日志系统启动");

    return true;
}

// 记录操作日志到数据库
bool Logger::logOperation(const QString &operationType,
                          const QString &targetObject,
                          const QString &description,
                          const QString &userName,
                          const QString &result,
                          const QString &errorMessage)
{
    if (!m_initialized)
    {
        qWarning() << "日志系统未初始化";
        return false;
    }

    QSqlDatabase db = DatabaseService::instance()->database();
    QSqlQuery query(db);

    query.prepare(R"(
        INSERT INTO operation_logs 
        (timestamp, user_name, operation_type, target_object, description, result, error_message) 
        VALUES (datetime('now', 'localtime'), ?, ?, ?, ?, ?, ?)
    )");

    query.addBindValue(userName.isEmpty() ? "system" : userName);
    query.addBindValue(operationType);
    query.addBindValue(targetObject);
    query.addBindValue(description);
    query.addBindValue(result);
    query.addBindValue(errorMessage);

    if (!query.exec())
    {
        qWarning() << "操作日志记录失败:" << query.lastError().text();
        return false;
    }

    return true;
}

// 记录日志到文件
void Logger::logToFile(LogLevel level, const QString &message)
{
    if (!m_fileLoggingEnabled || !m_logStream)
        return;

    // 日志级别过滤
    if (level < m_logLevel)
        return;

    QMutexLocker locker(&s_mutex);

    QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
    QString levelStr = logLevelToString(level);
    QString logLine = QString("[%1] [%2] %3\n").arg(timestamp, levelStr, message);

    *m_logStream << logLine;
    m_logStream->flush();

    emit logRecorded(levelStr, message, timestamp);
}

// 便捷方法：记录调试日志
void Logger::debug(const QString &message)
{
    qDebug() << message;
    logToFile(Debug, message);
}

// 便捷方法：记录信息日志
void Logger::info(const QString &message)
{
    qInfo() << message;
    logToFile(Info, message);
}

// 便捷方法：记录警告日志
void Logger::warning(const QString &message)
{
    qWarning() << message;
    logToFile(Warning, message);
}

// 便捷方法：记录严重错误日志
void Logger::critical(const QString &message)
{
    qCritical() << message;
    logToFile(Critical, message);
}

// 关闭日志系统
void Logger::close()
{
    if (m_logStream)
    {
        delete m_logStream;
        m_logStream = nullptr;
    }

    if (m_logFile)
    {
        if (m_logFile->isOpen())
        {
            m_logFile->close();
        }
        delete m_logFile;
        m_logFile = nullptr;
    }

    m_initialized = false;
}

// 将日志级别转换为字符串
QString Logger::logLevelToString(LogLevel level)
{
    switch (level)
    {
    case Debug:
        return "DEBUG";
    case Info:
        return "INFO";
    case Warning:
        return "WARNING";
    case Critical:
        return "CRITICAL";
    case Fatal:
        return "FATAL";
    default:
        return "UNKNOWN";
    }
}
